package org.misty.practices.classloader;

import sun.misc.Unsafe;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class DefineAnonymousClassSample {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, URISyntaxException, IOException, InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
        var field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        var unsafe = (Unsafe) field.get(null);
        System.out.println(unsafe);

        var url = DefineAnonymousClassSample.class.getResource("Bird.class");
        var bytes = Files.readAllBytes(Paths.get(url.toURI()));

        var klass1 = unsafe.defineAnonymousClass(DefineAnonymousClassSample.class, bytes, null);
        var klass2 = unsafe.defineAnonymousClass(DefineAnonymousClassSample.class, bytes, null);
        System.out.println(klass1 == klass2); // false

        Flyable bird1 = (Flyable) klass1.getDeclaredConstructor().newInstance();
        bird1.fly();

        Flyable bird2 = (Flyable) klass2.getDeclaredConstructor().newInstance();
        bird2.fly();

        var klass3 = Class.forName("org.misty.practices.classloader.Bird");
        Flyable bird3 = (Flyable) klass3.getDeclaredConstructor().newInstance();
        bird3.fly();
    }
}
